package com.example.Lezedata.net;

import android.os.Bundle;
import android.util.Log;

import com.androidnetworking.AndroidNetworking;
import com.androidnetworking.error.ANError;
import com.androidnetworking.interfaces.JSONObjectRequestListener;
import com.example.Lezedata.dataManager.GBUserManager;
import com.example.Lezedata.dataManager.LoginManager;
import com.example.Lezedata.ui.activity.baseClass.GBBaseVc;
import com.example.Lezedata.util.GBTimeManager;
import com.example.Lezedata.util.GBUtil;

import org.json.JSONObject;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.security.auth.callback.Callback;

import api.Api;
import api.BidServiceGrpc;
import api.BidUserServiceGrpc;
import bid.Bid;
import io.grpc.CallOptions;
import io.grpc.Channel;
import io.grpc.ClientCall;
import io.grpc.ClientInterceptor;
import io.grpc.ClientInterceptors;
import io.grpc.ForwardingClientCall;
import io.grpc.ForwardingClientCallListener;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.Metadata;
import io.grpc.MethodDescriptor;

import io.grpc.Status;
import io.grpc.stub.MetadataUtils;

class HeaderClientInterceptor implements ClientInterceptor {

    private static final String TAG = "HeaderClientInterceptor";

    private Map<String, String> mHeaderMap;

    public HeaderClientInterceptor(Map<String, String> headerMap) {
        mHeaderMap = headerMap;
    }

    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
                                                               CallOptions callOptions, Channel next) {
        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {

            @Override
            public void start(Listener<RespT> responseListener, Metadata headers) {
                /* put custom header */
                if (mHeaderMap != null) {
                    for (String key : mHeaderMap.keySet()) {
                        Metadata.Key<String> customHeadKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER);
                        headers.put(customHeadKey, mHeaderMap.get(key));
                    }
                }
                Log.d(TAG, "header send to server:" + headers);
                super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
                    @Override
                    public void onHeaders(Metadata headers) {
                        /**
                         * if you don't need receive header from server,
                         * you can use {@link MetadataUtils attachHeaders}
                         * directly to send header
                         */
                        Log.d(TAG, "header received from server:" + headers);
                        super.onHeaders(headers);
                    }

                    @Override
                    public void onMessage(RespT message) {
                        super.onMessage(message);
                    }

                    @Override
                    public void onClose(Status status, Metadata trailers) {
                        super.onClose(status, trailers);
                    }

                    @Override
                    public void onReady() {
                        super.onReady();
                    }
                }, headers);
            }
        };
    }
}

public class GBNetRequest {
    public static ManagedChannel managedChannel;

    public static GBNetRequest newInstance() {
        GBNetRequest fragment = new GBNetRequest();
        return fragment;
    }

    public GBNetRequest(){
        init();
    }

    private void init() {
        try {
             managedChannel = ManagedChannelBuilder.forAddress("h5.bzz.dev", 80)
                    .usePlaintext()
                    .disableRetry()
                    .idleTimeout(2, TimeUnit.SECONDS)
                    .build();
        } catch (Exception ex) {
            Log.d("TAG", "init: ");
        }
    }

    public static BidServiceGrpc.BidServiceStub stub(){
        ClientInterceptor interceptor = new HeaderClientInterceptor(headerMap());
        Channel channel = ClientInterceptors.intercept(managedChannel, interceptor);
        BidServiceGrpc.BidServiceStub stub = BidServiceGrpc.newStub(channel);
        return stub;
    }

    public static BidUserServiceGrpc.BidUserServiceStub stubUser(){
        ClientInterceptor interceptor = new HeaderClientInterceptor(headerMap());
        Channel channel = ClientInterceptors.intercept(managedChannel, interceptor);
        BidUserServiceGrpc.BidUserServiceStub stub = BidUserServiceGrpc.newStub(channel);
        return stub;
    }

    public static HashMap<String, String> headerMap(){
        HashMap<String, String> headerMap = new HashMap<String, String>();
        String userId = GBUserManager.getUserId();
        String deviceId = GBUtil.getDeviceId();
        String model = android.os.Build.MODEL;
        long timestamp = GBTimeManager.timestamp();

        headerMap.put("x-bid-userid",userId);
        headerMap.put("x-bid-deviceid",deviceId);
        headerMap.put("x-bid-timestamp",String.valueOf(timestamp));
        headerMap.put("x-bid-token", GBUserManager.instance().token);
        headerMap.put("x-bid-model",model);
        headerMap.put("x-bid-client","android");
        headerMap.put("x-bid-language","english");
        headerMap.put("x-bid-app","bid");
        return headerMap;
    }
}
